%{
/*********************************************
YACC file
2112433 石长伟
基础程序
为运算符和整数定义单词类别，在yylex内实现代码能识别这些单词，并将单词类别返回给词法分析程序
**********************************************/
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
#ifndef YYSTYPE
#define YYSTYPE double
#endif
int yylex();
extern int yyparse();
FILE* yyin;
void yyerror(const char* s);
%}
//注意先后定义的优先级区别
%token ADD MINUS
%token MULT DIV
%token UMINUS
%token LPAR RPAR
%token NUMBER 

%left ADD MINUS
%left MULT DIV
%right UMINUS         
%left LPAR RPAR
%%


lines   :       lines expr '\n' { printf("%f\n", $2); }
        |       lines '\n'
        |
        ;

expr    :       expr ADD expr   { $$=$1+$3; }
        |       expr MINUS expr   { $$=$1-$3; }
        |       expr MULT expr   { $$=$1*$3; }
        |       expr DIV expr   { $$=$1/$3; }
        |       LPAR expr RPAR      { $$=$2;}
        |       MINUS expr %prec UMINUS   {$$=-$2;}
        |       NUMBER
        ;


%%

// programs section

int yylex()
{
    int t;
    while(1){
        t=getchar();
        if(isdigit(t)){
            yylval=t-'0';
            return NUMBER;
        }else if(t=='+'){
            return ADD;
        }else if(t=='-'){
            return MINUS;
        }else if(t=='*'){
            return MULT;
        }else if(t=='/'){
            return DIV;
        }else if(t=='('){
            return LPAR;
        }else if(t==')'){
            return RPAR;
        }
        else{
            return t;
        }
    }
}

int main(void)
{
    yyin=stdin;
    do{
        yyparse();
    }while(!feof(yyin));
    return 0;
}
void yyerror(const char* s){
    fprintf(stderr,"Parse error: %s\n",s);
    exit(1);
}
